import 'package:cloudapp/esdk/esync.dart';
import 'package:cloudapp/pages/album_viewer.dart';
import 'package:cloudapp/pages/local_picture_page.dart';
import 'package:cloudapp/pages/picture_list_page.dart';
import 'package:cloudapp/pages/picture_viewer.dart';
import 'package:cloudapp/pages/qrcode_scan.dart';
import 'package:cloudapp/pages/server_finding_page.dart';
import 'package:cloudapp/pages/video_player_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:provider/provider.dart';

import 'esdk/response/user_login_response.dart';
import 'esdk/storage.dart';
import 'model/login_user_info.dart';
import 'model/upload_list.dart';
import 'pages/cloud_album_page.dart';
import 'pages/esync_main.dart';
import 'pages/servers_page.dart';
import 'pages/user_login_page.dart';
import 'utils/tasks.dart';
import 'widgets/loading_page.dart';

//
void main() {
  WidgetsFlutterBinding.ensureInitialized();

  final app = ESyncApp();
  final upList = UploadList.i();

  runApp(MultiProvider(
    child: app,
    providers: [
      ChangeNotifierProvider<LoginUserInfo>(
        create: (_) => LoginUserInfo(),
      ),
      ChangeNotifierProvider<UploadList>(
        create: (_) => upList,
      ),
    ],
  ));

  startUploadThread();
}

class AppRouter {
  static Map<String, Function> routes = {
    UserLoginPage.pageName: (context) => UserLoginPage(),
    ESyncMainPage.pageName: (context) => ESyncMainPage(),
    CloudAlbumPage.pageName: (context) => CloudAlbumPage(),
    LocalPicturePage.pageName: (context) => LocalPicturePage(),
    ServerFindingPage.pageName: (context) => ServerFindingPage(),
    QRCodeScan.pageName: (context) => QRCodeScan(),
    ServersPage.pageName: (context) => ServersPage(),
    VideoPlayerPage.pageName: (context, {@required arguments}) => VideoPlayerPage(url: arguments),
    PictureListPage.pageName: (context, {@required int arguments}) => PictureListPage(albumId: arguments),
    PictureViewer.pageName: (context, {@required arguments}) => PictureViewer(source: arguments),
    AlbumViewerPage.pageName: (context, {@required arguments}) => AlbumViewerPage(arguments: arguments),
  };

  static run(RouteSettings settings) {
    var routeName = settings.name;
    var args = settings.arguments;
    final pageBuilder = AppRouter.routes[routeName];

    if(pageBuilder == null) {
      return MaterialPageRoute(builder: (context) => InitLoadingPage());
    }

    if(args == null) {
      // 无参
      return MaterialPageRoute(builder: (context) => pageBuilder(context));
    }

    /// picture viewer animate
    if(settings.name == AlbumViewerPage.pageName) {
      return PageRouteBuilder(
        pageBuilder: (_, __, ___) => AlbumViewerPage(arguments: args),
        transitionsBuilder: (context, an1, an2, child) {
          return ScaleTransition(
            scale: Tween(
              begin: 0.0,
              end: 1.0,
            ).animate(
              CurvedAnimation(
                parent: an1,
                curve: Curves.fastOutSlowIn,
              )
            ),
            child: child,
          );
        }
      );
    }
    return MaterialPageRoute(builder: (context) {
      return pageBuilder(context, arguments: args);
    });
  }
}

class ESyncApp extends StatelessWidget {
  Widget app(BuildContext ctx, Widget home) {
    return MaterialApp(
      home: home,
      theme: ThemeData(
        primaryColor: Colors.blue,
      ),
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const <Locale>[
        Locale('zh', 'CH'),
      ],
      onGenerateRoute: (RouteSettings settings) {
        return AppRouter.run(settings);
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    print('build whole app.');
    var f = initStorage();
    f.then((info) {
      final userInfo = Provider.of<LoginUserInfo>(context, listen: false);
      userInfo.login(info);
    });

    return FutureBuilder<UserLoginResponse>(
      future: f,
      builder: (BuildContext context, AsyncSnapshot<UserLoginResponse> snapshot) {
        var state = snapshot.connectionState;
        if(state != ConnectionState.done) {
          return app(context, InitLoadingPage());
        }

        var userInfo = snapshot.data;
        if(userInfo == null) {
          return app(context, UserLoginPage());
        }

        ESync.i().setToken(userInfo.userId, userInfo.accessToken);
        return app(context, CloudAlbumPage());
      },
    );
  }
}
